import axios from 'axios'
import { ElMessage } from 'element-plus'

// 创建axios实例
const api = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  }
})

// 请求拦截器
api.interceptors.request.use(
  (config) =>
  {
    // 关键修复：如果是FormData，完全删除Content-Type，让浏览器自动设置
    if (config.data instanceof FormData)
    {
      delete config.headers['Content-Type']
      console.log('[FormData检测] 删除Content-Type，让浏览器自动设置multipart/form-data')
    } else
    {
      config.headers['Content-Type'] = config.headers['Content-Type'] || 'application/json'
    }

    // 添加认证token
    const token = localStorage.getItem('token')
    if (token)
    {
      config.headers.Authorization = `Bearer ${token}`
    }

    // 添加追踪ID
    config.headers['X-Trace-Id'] = generateTraceId()

    // 显示加载状态
    if (!config.hideLoading)
    {
      // 这里可以显示全局loading
      config.metadata = { showLoading: true }
    }

    // 开发环境下记录请求信息
    if (import.meta.env.DEV)
    {
      console.log(`[API Request] ${config.method?.toUpperCase()} ${config.url}`, {
        data: config.data instanceof FormData ? 'FormData对象' : config.data,
        headers: config.headers
      })
    }
    return config
  },
  (error) =>
  {
    console.error('[API Request Error]', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
api.interceptors.response.use(
  (response) =>
  {
    const { config, data } = response

    // 隐藏加载状态
    if (config.metadata?.showLoading)
    {
      // 隐藏loading
    }

    // 开发环境下记录响应信息
    if (import.meta.env.DEV)
    {
      console.log(`[API Response] ${config.method?.toUpperCase()} ${config.url}`, data)
    }

    // 检查业务状态码
    if (data.code !== undefined && data.code !== 200)
    {
      const errorMessage = data.message || '请求失败'

      // 根据错误码进行不同处理
      switch (data.code)
      {
        case 2000: // 未授权
        case 2002: // Token无效
        case 2003: // Token过期
          handleAuthError(errorMessage)
          break
        case 1001: // 参数错误
          ElMessage.error(errorMessage)
          break
        case 1002: // 资源不存在
          ElMessage.warning(errorMessage)
          break
        case 5000: // 请求过于频繁
          ElMessage.warning('请求过于频繁，请稍后再试')
          break
        default:
          ElMessage.error(errorMessage)
      }

      // 返回一个rejected promise
      const error = new Error(errorMessage)
      error.code = data.code
      error.traceId = data.traceId
      return Promise.reject(error)
    }

    return data
  },
  (error) =>
  {
    // 隐藏加载状态
    if (error.config?.metadata?.showLoading)
    {
      // 隐藏loading
    }

    let errorMessage = '请求失败'

    if (error.response)
    {
      // 服务器返回了错误状态码
      const { status, data } = error.response

      switch (status)
      {
        case 400:
          errorMessage = data?.message || '请求参数错误'
          break
        case 401:
          errorMessage = '未授权，请重新登录'
          handleAuthError(errorMessage)
          return Promise.reject(error)
        case 403:
          errorMessage = '权限不足，无法访问'
          break
        case 404:
          errorMessage = '请求的资源不存在'
          break
        case 429:
          errorMessage = '请求过于频繁，请稍后再试'
          break
        case 500:
          errorMessage = '服务器内部错误'
          break
        case 502:
          errorMessage = '网关错误'
          break
        case 503:
          errorMessage = '服务暂时不可用'
          break
        default:
          errorMessage = data?.message || `请求失败 (${status})`
      }
    } else if (error.request)
    {
      // 请求已发出但没有收到响应
      if (error.code === 'ECONNABORTED')
      {
        errorMessage = '请求超时，请检查网络连接'
      } else
      {
        errorMessage = '网络连接失败，请检查网络设置'
      }
    }

    // 显示错误消息
    if (!error.config?.hideErrorMessage)
    {
      ElMessage.error(errorMessage)
    }

    const enhancedError = new Error(errorMessage)
    enhancedError.originalError = error
    enhancedError.status = error.response?.status
    enhancedError.traceId = error.response?.data?.traceId

    return Promise.reject(enhancedError)
  }
)

// 处理认证错误
function handleAuthError(message)
{
  // 清除本地token
  localStorage.removeItem('token')
  localStorage.removeItem('user_info')

  // 显示错误消息
  ElMessage.error(message)

  // 延迟跳转到登录页
  setTimeout(() =>
  {
    if (window.location.pathname !== '/login')
    {
      window.location.href = '/login'
    }
  }, 1500)
}

// 生成追踪ID
function generateTraceId()
{
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}

// API方法封装
export const ApiClient = {
  // GET请求
  get(url, params = {}, config = {})
  {
    console.log('🌐 API GET请求:', {
      url,
      params,
      config,
      fullUrl: `${api.defaults.baseURL}${url}`
    })
    return api.get(url, { params, ...config })
  },

  // POST请求
  post(url, data = {}, config = {})
  {
    return api.post(url, data, config)
  },

  // PUT请求
  put(url, data = {}, config = {})
  {
    return api.put(url, data, config)
  },

  // DELETE请求
  delete(url, config = {})
  {
    return api.delete(url, config)
  },

  // PATCH请求
  patch(url, data = {}, config = {})
  {
    return api.patch(url, data, config)
  },

  // 文件上传
  upload(url, formData, config = {})
  {
    return api.post(url, formData, {
      // 对于 FormData，请求拦截器已经处理了 Content-Type
      // 浏览器会自动设置为 multipart/form-data 并包含正确的边界标识符
      ...config
    })
  },

  // 文件下载
  download(url, params = {}, filename = null)
  {
    return api.get(url, {
      params,
      responseType: 'blob'
    }).then(response =>
    {
      // 创建下载链接
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename || getFilenameFromResponse(response) || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    })
  }
}

// 从响应头获取文件名
function getFilenameFromResponse(response)
{
  const contentDisposition = response.headers['content-disposition']
  if (contentDisposition)
  {
    const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)
    if (match && match[1])
    {
      return match[1].replace(/['"]/g, '')
    }
  }
  return null
}

export default api

// 导出常用的API方法
export const { get, post, put, patch, delete: del, upload, download } = ApiClient
